<template>
  <div id="app"
  @mousemove='mouseMove'
  ref = 'app'
  >
    <control-bar
      ref="controlBar"
      @save="save"
      @revoke="revoke"
      @restore="restore"
      @addColorMedium='addColorMedium'
      @removeColorMedium='removeColorMedium'
      @addColorBasic="addColorBasic"
      @removeColorBasic="removeColorBasic"
    ></control-bar>

    <color-tags
      id='colorTags'
      ref='colorTags'
      :color_mediums='color_mediums'
      :color_basics='color_basics'
      @pickColorTag='pickColorTag'
      @moveColorBasic='moveColorBasic'
      >
      </color-tags>
    <color-square-content
      :colors="colors"
      :current_idx="current_color_idx"
      @moveColor="moveColor"
      
    ></color-square-content>
    
  </div>
</template>

<script>
import colorTags from "./components/colortags.vue";
import colorSquareContent from "./components/colorsquarecontent.vue";
import controlBar from "./components/controlbar.vue";

export default {
  name: "App",
  components: {
    colorTags,
    colorSquareContent,
    controlBar,
  },
  data() {
    return {
      color_mediums:[],
      color_basics:[],
      colors: [[["red", "red"]], [["yellow", "yellow"]], [["green", "green"]]],
      unsaved_changes: [],
      change_records: [],
      current_step: 0,
      current_tag_idx:[0,0],
      current_color_idx:0,
      active_idx:[],
      mouseMove:()=>{}
    };
  },
  computed: {
    length_medium() {
      return this.color_mediums.length;
    },
    length_basic() {
      let len = 0
      for(let i=0;i<this.length_medium;i++){
        len += this.color_basics[i].length
      }
      return len;
    },
    length_color() {
      return this.colors.length;
    },
    length_change() {
      return this.change_records.length;
    },
    none_idx() {
      let idx = 0;
      for (let i = 0; i < this.length_basic; i++) {
        for(let j=0;j<this.color_basics[i].length;j++){
          if (this.color_basics[i][j].indexOf("待定") != -1) {
            return idx + j;
          }
        }
        idx += this.color_basics[i].length
      }
      return 0
    },
  },
  created() {
    
    setTimeout(()=>{
      this.mouseMove = this._.throttle((e)=>{
          let [x,y] = [e.pageX,e.pageY]
          this.freshOver()
          this.active_idx = this.$refs.colorTags.isOverBasic(x,y)
      },10)
      
    },400)

    this.axios
      .get("/colorClassifier/get_color_tags")
      .then((response) => {
        [this.color_mediums,this.color_basics] = response.data.color_tags;
      })
      .catch(function (error) {
        console.log(error);
      });

    this.axios
      .get("/colorClassifier/get_colors")
      .then((response) => {
        this.colors = response.data.colors;
      })
      .catch(function (error) {
        console.log(error);
      });
  },
  mounted(){
    window.onbeforeunload = function (e) {
      e = e || window.event;
      if (e) {
        e.returnValue = '关闭提示';
      }
      return '关闭提示';
    };
    console.log(this.$refs.app.offsetWidth)
  },
  methods: {
    get_idx(medium_idx,basic_idx){
      let idx = 0
      for(let i=0;i<medium_idx;i++){
        idx += this.color_basics[i].length
      }
      return idx + basic_idx
    },
    name_to_idx(name){
      for(let i=0;i<this.length_medium;i++){
        for(let j=0;j<this.color_basics[i].length;j++){
          // console.log(this.color_basics[i][j])
          if (this.color_basics[i][j][0] == name){
            return this.get_idx(i,j)
          }
        }
      }
    },
    idx_to_name(index){
      let idx = 0
      for(let i=0;i<this.length_medium;i++){
        for(let j=0;j<this.color_basics[i].length;j++){
          if (idx == index){
            return this.color_basics[i][j][0]
          }
          idx++;
        }
      }
    },
    freshOver(){
      for(let i=0;i<this.length_medium;i++){
        let color_basics = this.$refs.colorTags.$refs.colorMedium[i].$refs.colorBasic
        for(let j=0;j<color_basics.length;j++){
          color_basics[j].$el.style["background-color"] =
              "rgb" + this.color_basics[i][j][1];
        }
      }
    },
    pickColorTag(medium_idx,basic_idx,rePick=false){
      this.current_tag_idx = [medium_idx,basic_idx]
      this.current_color_idx = this.get_idx(medium_idx,basic_idx)
      if(rePick){
        this.$refs.colorTags.medium_idx = medium_idx
        this.$refs.colorTags.basic_idx = basic_idx
        this.$refs.colorTags.$refs.colorMedium[medium_idx].current_idx = basic_idx
      }
    },
    changeUnsaved(record, save) {
      let [ifSave, plus, newRecord] = save;
      if (!ifSave) {
        return;
      }
      if (newRecord) {
        this.change_records.splice(
          this.current_step,
          this.length_change - this.current_step,
          record
        );
      }
      if (plus) {
        this.current_step++;
      } else {
        this.current_step--;
      }
      this.unsaved_changes.push(record);
      if (this.$refs.controlBar.autoSave) {
        this.save();
      }
    },
    moveColorBasic(medium_idx,basic_idx){
      console.log('app','opCB',medium_idx,basic_idx)
      if(this.active_idx[0] == this.current_tag_idx[0]){
        return
      }
      if (this.active_idx[0] >= 0) {
        this.opColorBasic(
        [medium_idx,basic_idx,this.color_mediums[medium_idx],this.color_basics[medium_idx][basic_idx]],
        [this.active_idx[0],0,this.color_mediums[this.active_idx[0]],this.color_basics[medium_idx][basic_idx]],
        this.colors[this.get_idx(medium_idx,basic_idx)]);
      }
    },
    moveColor(bgcs) {
      if(this.active_idx[1] == -1){
        return;
      }
      let target_idx = this.get_idx(this.active_idx[0],this.active_idx[1])
      if (target_idx >= 0) {
        this.opColor(this.current_color_idx, target_idx, bgcs);
      }
    },

    opColorBasic(
      current,
      target,
      bgcs,
      save = [true, true, true]
    ){
      bgcs = bgcs.slice(0, bgcs.length);
      let medium_idx,basic_idx
      console.log('opB',current,target)
      if (target == -1) {
        [medium_idx,basic_idx] = [current[0],current[1]]
        current.push(this.color_mediums[medium_idx])
        let idx = this.get_idx(medium_idx,basic_idx)
        this.opColor(idx, this.none_idx, bgcs, [false]);
        this.color_basics[medium_idx].splice(basic_idx, 1);
        this.colors.splice(idx, 1);
      }
      else if(current == -1) {
        [medium_idx,basic_idx] = [target[0],target[1]]
        target.push(this.color_mediums[medium_idx])
        let idx = this.get_idx(medium_idx,basic_idx)
        let tmp=this.color_basics[medium_idx].splice(0,this.color_basics[medium_idx].length)
        tmp.splice(basic_idx,0,target[2])
        this.$set(this.color_basics,medium_idx,tmp)
        this.colors.splice(idx, 0, []);
        this.opColor(this.none_idx, idx, bgcs, [false]);
      }
      else{
        console.log(current,target)
        let [[current_medium_idx,current_basic_idx],[target_medium_idx,target_basic_idx]] = [current,target]
        let [current_idx,target_idx] = [this.get_idx(current_medium_idx,current_basic_idx),this.get_idx(target_medium_idx,target_basic_idx)]
        let target_basics=this.color_basics[target_medium_idx].slice(0,this.color_basics[target_medium_idx].length)
        let current_basics=this.color_basics[current_medium_idx].slice(0,this.color_basics[current_medium_idx].length)
        target_basics.splice(target_basic_idx,0,this.color_basics[current_medium_idx][current_basic_idx])
        current_basics.splice(current_basic_idx,1)
        this.$set(this.color_basics,target_medium_idx,target_basics)
        this.$set(this.color_basics,current_medium_idx,current_basics)

        this.colors.splice(target_idx, 0, []);
        if(current_idx>target_idx){
          current_idx += 1
        }
        this.opColor(current_idx, target_idx, bgcs, [false]);
        this.colors.splice(current_idx, 1);
        this.pickColorTag(target[0],target[1],true)
      }
      this.changeUnsaved([current, target, bgcs], save);
    },
    opColorMedium(
      current,
      target,
      basics,
      save = [true, true, true]
    ){
      console.log('opCM',current,target,basics)
      if(current == -1){
        this.color_mediums.splice(target[0],0,target[1])
        this.color_basics.splice(target[0],0,[])
        for(let i=0;i<basics.length;i++){
          this.opColorBasic(-1, [target[0],i,basics[i][0]], basics[i][1],[false]);
        }
      }
      if(target == -1){
        basics = this.color_basics[current[0]].slice(0,this.color_basics[current[0]].length)
        for(let i=0;i<basics.length;i++){
          let bgcs = this.colors[this.get_idx(current[0],0)]
          basics[i] = [basics[i],bgcs.slice(0,bgcs.length)]
          console.log(i,basics[i],this.get_idx(current[0],0),this.none_idx)
          this.opColorBasic([current[0],0,basics[i][0]], -1, basics[i][1],[false]);
        }
        this.color_mediums.splice(current[0],1)
        this.color_basics.splice(current[0],1)
      }
      this.changeUnsaved([current, target,basics], save);
    },
    opColor(current_idx, target_idx, bgcs, save = [true, true, true]) {
      if(typeof(current_idx)=='string'){
        current_idx = this.name_to_idx(current_idx)
      }
      if(typeof(target_idx)=='string'){
        target_idx = this.name_to_idx(target_idx)
      }
      console.log('opC',current_idx,target_idx)
      let current = this.colors[current_idx]//.slice(0,this.colors[current_idx].length);
      bgcs = bgcs.slice(0, bgcs.length);
      for (let i = 0; i < bgcs.length; i++) {
        let bgc = bgcs[i];
        current.splice(current.indexOf(bgc), 1);
        this.colors[target_idx].unshift(bgc);
      }
      this.changeUnsaved([this.idx_to_name(current_idx), this.idx_to_name(target_idx), bgcs], save);
    },
    addColorMedium(color_name) {
      if (color_name == undefined) {
        alert("请先添加色类名称！");
        return;
      }
      let color_tag = [color_name, "(255,255,255)",];
      this.opColorMedium(-1, [this.color_mediums.length-1,color_tag],[[color_tag,[]],]);
    },
    removeColorMedium() {
      alert('正在删除色组！')
      let color_tag = this.color_mediums[this.current_tag_idx[0]];
      if(color_tag[0]=='待定'){
        alert('禁止删除待定区！')
        return;
      }
      this.opColorMedium([this.current_tag_idx[0],color_tag], -1,);
    },
    addColorBasic(color_name) {
      if (color_name == undefined) {
        alert("请先添加色类名称！");
        return;
      }
      let color_tag = [color_name, "(255,255,255)"];
      this.opColorBasic(-1, [this.length_medium-1,this.color_basics[this.length_medium-1].length,color_tag], [],);
    },
    removeColorBasic() {
      let color_tag = this.color_basics[this.current_tag_idx[0]][this.current_tag_idx[1]];
      if(color_tag[0]=='待定'){
        alert('禁止删除待定区！')
        return;
      }
      if(this.color_basics[this.current_tag_idx[0]].length == 1){
        alert('这是本组的最后一个色类，若要删除请直接删除色组！')
        return 
      }
      let bgcs = this.colors[this.current_color_idx];
      this.opColorBasic([this.current_tag_idx[0],this.current_tag_idx[1],color_tag], -1, bgcs,);
    },
    revoke() {
      if (this.current_step == 0) {
        alert("没有可以撤销的对象");
        return;
      }
      let re_record = this.change_records[this.current_step - 1];
      let [re_current, re_target, bgcs] = re_record;
      console.log('revoke',this.current_step,re_current,re_target)
      let save = [true, false, false];
      if(re_current.length == 2 && re_target==-1|| re_target.length == 2 && re_current==-1){
          this.opColorMedium(re_target,re_current,bgcs,save)
      }
      else if (re_current == -1||re_target==-1 || re_current.length == 4 && re_target.length == 4) {
          this.opColorBasic(re_target, re_current, bgcs, save);
      }
      else {
        this.opColor(re_target, re_current, bgcs, save);
      }
    },
    restore(pre=0) {
      if (this.current_step == this.change_records.length) {
        alert("没有可以恢复的对象");
        return;
      }
      
      let re_record = this.change_records[this.current_step+pre];
      let [re_current, re_target, bgcs] = re_record;
      console.log('restore',this.current_step,re_current,re_target)
      let save = [true, true, false];
      if(re_current.length == 2 && re_target==-1|| re_target.length == 2 && re_current==-1){
          this.opColorMedium(re_current,re_target,bgcs,save)
      }
      else if (re_current == -1 || re_target==-1||re_current.length == 2 && re_target.length == 2) {
          this.opColorBasic(re_current, re_target, bgcs, save);
      }
      else {
        this.opColor(re_current, re_target, bgcs, save);
      }
    },
    save() {
      if (this.unsaved_changes.length == 0) {
        alert("没有需要保存的对象");
        return;
      }
      let params = new URLSearchParams();
      params.set("unsaved_changes", JSON.stringify(this.unsaved_changes));
      this.axios
        .post("/colorClassifier/changeColor", params)
        .then((response) => {
          this.unsaved_changes = [];
          console.log(response);
        })
        .catch(function (error) {
          console.log(error);
        });
    },
    
  },
};
</script>
        
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-user-select:none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  /* margin-top: 60px; */
}

#colorTags {
  width:80%;
  margin:0 10%
}
</style>
